import { RouteRecordRaw} from "vue-router";
import {defineStore} from "pinia";
import {constantRoutes} from "@/router";
import {isNotEmptyArray} from "@/utils/common-fn";
import {listRoutesApi} from "@/api/sys/admin/auth";
import {Role, RouterName} from "@/utils/enum-type";

const modules = import.meta.glob("../../views/**/**.vue");

/**
 * Use meta.role to determine if the current user has permission
 *
 * @param roles 用户角色集合
 * @param route 路由
 * @returns
 */
const hasPermission = (roles: string[], route: RouteRecordRaw) => {
    if (route.meta && route.meta.roles) {
        // 角色【超级管理员】拥有所有权限，忽略校验
        if (roles.includes(Role.Root)) {
            return true;
        }
        return roles.some((role) => {
            if (route.meta?.roles !== undefined) {
                return (route.meta.roles as string[]).includes(role);
            }
        });
    }
    return false;
};

/**
 * 递归过滤有权限的异步(动态)路由
 *
 * @param routes 接口返回的异步(动态)路由
 * @param roles 用户角色集合
 * @returns 返回用户有权限的异步(动态)路由
 */
const filterAsyncRoutes = (routes: RouteRecordRaw[], roles: string[]) => {
    const asyncRoutes: RouteRecordRaw[] = [];

    routes.forEach((route) => {
        const tmpRoute = {...route}; // ES6扩展运算符复制新对象
        // 判断用户(角色)是否有该路由的访问权限
        if (hasPermission(roles, tmpRoute)) {
            if (tmpRoute.component) {
                const component = modules[`../../views/sys/${tmpRoute.component}.vue`];
                if (component) {
                    tmpRoute.component = component;
                } else {
                    tmpRoute.component = modules[`../../views/error-page/404.vue`];
                }
            }
            if (tmpRoute.children) {
                tmpRoute.children = filterAsyncRoutes(tmpRoute.children, roles);
            }
            if (!tmpRoute.component && !isNotEmptyArray(tmpRoute.children)) {
                // 如果没有component和children属性
                tmpRoute.component = modules[`../../views/error-page/404.vue`];
            }

            asyncRoutes.push(tmpRoute);
        }
    });

    return asyncRoutes;
};

// setup
export const usePermissionStore = defineStore("permission", () => {
    // state
    const routes = ref<RouteRecordRaw[]>([]);

    // 当前顶部的名称
    const baseUrl = ref('/')

    // actions
    function setRoutes(newRoutes: RouteRecordRaw[]) {
        getDynamicRoutes().push(...newRoutes)
        // 全部路由设置进去
        routes.value = constantRoutes
    }

    // 获取动态路由
    function getDynamicRoutes(){
        // 这里用了很多!,因为我在路由中写死了部分路由,所以这些值不用判断,前提是我不修改我的路由
        return constantRoutes.find(item => item.path === '/')!
            .children!.find(item => item.name === RouterName.Sys)!
            .children!
    }


    /**
     * 生成动态路由
     *
     * @param roles 用户角色集合
     * @returns
     */
    async function generateRoutes(roles: string[]) {
        // 接口获取所有路由
        const allRoutes = await listRoutesApi()
        // 根据角色获取有访问权限的路由
        const accessedRoutes = filterAsyncRoutes(allRoutes, roles);
        setRoutes(accessedRoutes);
        // console.log('最后生成的路由为:', accessedRoutes)
        return accessedRoutes;
    }

    return {
        baseUrl, routes,
        generateRoutes,getDynamicRoutes
    };
})
